import pyaudio
import wave
import numpy as np
import audioop
import time

notes = {
    "1": 262,
    "1#": 277,
    "2": 294,
    "2#": 311,
    "3": 330,
    "4": 349,
    "4#": 370,
    "5": 392,
    "5#": 415,
    "6": 440,
    "6#": 466,
    "7": 494
}

def findNote(freq):
    delta = 1000
    closest = "1"
    for key in notes:
        if freq % notes[key] < freq % notes[closest]:
            closest = key
    return closest

CHUNK = 2048
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)
print("* recording")
frames = []
# for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
#     data = stream.read(CHUNK)
#     frames.append(data)

window = np.blackman(CHUNK)

while True:
    data = stream.read(CHUNK)
    rms = audioop.rms(data, 2)
    volumn = 20 * np.log10(rms)
    indata = np.array(wave.struct.unpack("%dh" % (len(data) / 2), data)) * window
    fftData = abs(np.fft.rfft(indata)) ** 2
    which = fftData[1:].argmax() + 1

    if volumn > 65:
        y0, y1, y2 = np.log(fftData[which - 1:which + 2:])
        x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
        # find the frequency and output it
        thefreq = (which + x1) * RATE / CHUNK
        print "The freq is %f Hz." % (thefreq)
        note = findNote(thefreq)
        print note








# print("* done recording")
# stream.stop_stream()
# stream.close()
# p.terminate()
# wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
# wf.setnchannels(CHANNELS)
# wf.setsampwidth(p.get_sample_size(FORMAT))
# wf.setframerate(RATE)
# wf.writeframes(b''.join(frames))
# wf.close()
